convert osm to format class (#579)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Mon, 1 Jun 2020 20:49:29 +0000 (14:49 -0600)
committerGitHub <noreply@github.com>
Mon, 1 Jun 2020 20:49:29 +0000 (14:49 -0600)
* convert osm to Format class.

* use static function cb w/o lambdas.

CMakeLists.txt
GPSBabel.pro
Makefile.in
osm.cc
osm.h [new file with mode: 0644]
vecs.h

index 97e83cc5ae3cbd61438e4c6b7c4539ba7b58fd68..393727d38d8807a6cb0f3d76467328b72ba95e48 100644 (file)
@@ -158,6 +158,7 @@ set(HEADERS
   mynav.h
   navilink.h
   nmea.h
+  osm.h
   random.h
   session.h
   shape.h
index e4429d9a976015818ca2b5eb850d24311ace2120..4b6c35e49b88f5fe14d3ddca059d793c4f645bc4 100644 (file)
@@ -143,6 +143,7 @@ HEADERS =  \
        mynav.h \
        navilink.h \
        nmea.h \
+       osm.h \
        random.h \
        session.h \
        shape.h \
index a076f4db1a8e7d63ed291184ea369d9aed953e78..5d34efdd723dd99f846ac45d6d4e54794bd219b6 100644 (file)
@@ -511,12 +511,12 @@ filter_vecs.o: filter_vecs.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   dg-100.h format.h energympro.h garmin_fit.h geojson.h src/core/file.h \
   ggv_bin.h globalsat_sport.h gpx.h src/core/xmlstreamwriter.h \
   src/core/xmltag.h kml.h xmlgeneric.h legacyformat.h lowranceusr.h \
-  mynav.h nmea.h qstarz_bl_1000.h random.h shape.h shapelib/shapefil.h \
-  subrip.h unicsv.h src/core/textstream.h xcsv.h garmin_fs.h jeeps/gps.h \
-  jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
-  jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
-  jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
-  jeeps/gpsrqst.h yahoo.h
+  mynav.h nmea.h osm.h qstarz_bl_1000.h random.h shape.h \
+  shapelib/shapefil.h subrip.h unicsv.h src/core/textstream.h xcsv.h \
+  garmin_fs.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \
+  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
+  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
+  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h yahoo.h
 formspec.o: formspec.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   formspec.h inifile.h gbfile.h session.h src/core/datetime.h \
   src/core/optional.h
@@ -536,7 +536,7 @@ garmin.o: garmin.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   jeeps/gpsrqst.h garmin_tables.h grtcirc.h jeeps/gpsserial.h vecs.h \
   dg-100.h energympro.h garmin_fit.h geojson.h src/core/file.h ggv_bin.h \
   globalsat_sport.h gpx.h src/core/xmlstreamwriter.h src/core/xmltag.h \
-  kml.h xmlgeneric.h legacyformat.h lowranceusr.h mynav.h nmea.h \
+  kml.h xmlgeneric.h legacyformat.h lowranceusr.h mynav.h nmea.h osm.h \
   qstarz_bl_1000.h random.h shape.h shapelib/shapefil.h subrip.h \
   unicsv.h src/core/textstream.h xcsv.h yahoo.h
 garmin_device_xml.o: garmin_device_xml.cc defs.h config.h zlib/zlib.h \
@@ -817,13 +817,13 @@ lowranceusr.o: lowranceusr.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   src/core/optional.h lowranceusr.h format.h src/core/logging.h
 maggeo.o: maggeo.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
-  csv_util.h magellan.h xmlgeneric.h
+  csv_util.h magellan.h
 magproto.o: magproto.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   formspec.h inifile.h gbfile.h session.h src/core/datetime.h \
   src/core/optional.h explorist_ini.h format.h gbser.h magellan.h vecs.h \
   dg-100.h energympro.h garmin_fit.h geojson.h src/core/file.h ggv_bin.h \
   globalsat_sport.h gpx.h src/core/xmlstreamwriter.h src/core/xmltag.h \
-  kml.h xmlgeneric.h legacyformat.h lowranceusr.h mynav.h nmea.h \
+  kml.h xmlgeneric.h legacyformat.h lowranceusr.h mynav.h nmea.h osm.h \
   qstarz_bl_1000.h random.h shape.h shapelib/shapefil.h subrip.h \
   unicsv.h src/core/textstream.h xcsv.h garmin_fs.h jeeps/gps.h \
   jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
@@ -839,12 +839,12 @@ main.o: main.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   src/core/file.h src/core/usasciicodec.h vecs.h dg-100.h energympro.h \
   garmin_fit.h geojson.h ggv_bin.h globalsat_sport.h gpx.h \
   src/core/xmlstreamwriter.h src/core/xmltag.h kml.h xmlgeneric.h \
-  legacyformat.h lowranceusr.h mynav.h nmea.h qstarz_bl_1000.h random.h \
-  shape.h shapelib/shapefil.h subrip.h unicsv.h src/core/textstream.h \
-  xcsv.h garmin_fs.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h yahoo.h
+  legacyformat.h lowranceusr.h mynav.h nmea.h osm.h qstarz_bl_1000.h \
+  random.h shape.h shapelib/shapefil.h subrip.h unicsv.h \
+  src/core/textstream.h xcsv.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
+  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
+  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
+  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h yahoo.h
 mapasia.o: mapasia.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
 mapbar_track.o: mapbar_track.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
@@ -900,7 +900,7 @@ nukedata.o: nukedata.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   src/core/optional.h nukedata.h filter.h
 osm.o: osm.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
-  xmlgeneric.h
+  osm.h format.h xmlgeneric.h
 ozi.o: ozi.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
   csv_util.h jeeps/gpsmath.h jeeps/gpsport.h src/core/textstream.h \
@@ -1060,13 +1060,13 @@ vecs.o: vecs.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   vecs.h dg-100.h format.h energympro.h garmin_fit.h geojson.h \
   src/core/file.h ggv_bin.h globalsat_sport.h gpx.h \
   src/core/xmlstreamwriter.h src/core/xmltag.h kml.h xmlgeneric.h \
-  legacyformat.h lowranceusr.h mynav.h nmea.h qstarz_bl_1000.h random.h \
-  shape.h shapelib/shapefil.h subrip.h unicsv.h src/core/textstream.h \
-  xcsv.h garmin_fs.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h yahoo.h gbversion.h \
-  src/core/logging.h
+  legacyformat.h lowranceusr.h mynav.h nmea.h osm.h qstarz_bl_1000.h \
+  random.h shape.h shapelib/shapefil.h subrip.h unicsv.h \
+  src/core/textstream.h xcsv.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
+  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
+  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
+  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h yahoo.h \
+  gbversion.h src/core/logging.h
 vidaone.o: vidaone.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
 vitosmt.o: vitosmt.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
diff --git a/osm.cc b/osm.cc
index e7b86204d501b4cd79d81cbca2de12451ca3b6e9..ee6e758ae9af0dc63ed9717efb8973877a0a741b 100644 (file)
--- a/osm.cc
+++ b/osm.cc
 #include <QtCore/QHash>                 // for QHash
 #include <QtCore/QLatin1String>         // for QLatin1String
 #include <QtCore/QPair>                 // for QPair, operator==
-#include <QtCore/QString>               // for QString, operator+, operator==
+#include <QtCore/QString>               // for QString, operator==, operator+
 #include <QtCore/QStringRef>            // for QStringRef
-#include <QtCore/QVector>               // for QVector
 #include <QtCore/QXmlStreamAttributes>  // for QXmlStreamAttributes
-#include <QtCore/QtGlobal>              // for qPrintable
+#include <QtCore/QtGlobal>              // for qPrintable, QAddConst<>::Type
 
 #include "defs.h"
-#include "gbfile.h"                     // for gbfprintf, gbfclose, gbfopen, gbfile
+#include "osm.h"
+#include "gbfile.h"                     // for gbfprintf, gbfclose, gbfopen
 #include "src/core/datetime.h"          // for DateTime
-#include "xmlgeneric.h"                 // for cb_start, cb_end, xg_callback, xg_string, xg_cb_type, xml_deinit, xml_init, xml_read, xg_tag_mapping
+#include "xmlgeneric.h"                 // for xg_string, build_xg_tag_map, xml_deinit, xml_init, xml_read
 
-static char* opt_tag, *opt_tagnd, *created_by;
-
-static QVector<arglist_t> osm_args = {
-  { "tag", &opt_tag,   "Write additional way tag key/value pairs", nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr},
-  { "tagnd", &opt_tagnd,       "Write additional node tag key/value pairs", nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr },
-  { "created_by", &created_by, "Use this value as custom created_by value","GPSBabel", ARGTYPE_STRING, ARG_NOMINMAX, nullptr },
-};
 
 #define MYNAME "osm"
 
-static QHash<QString, const Waypoint*> waypoints;
-
-static QHash<QString, int> keys;
-struct osm_icon_mapping_t;
-static QHash<QPair<int, QString>, const osm_icon_mapping_t*> values;
-static QHash<QString, const osm_icon_mapping_t*> icons;
-
-static gbfile* fout;
-static int node_id;
-static int skip_rte;
-
-static route_head* rte;
-static Waypoint* wpt;
-
-static xg_callback     osm_node, osm_node_tag, osm_node_end;
-static xg_callback     osm_way, osm_way_nd, osm_way_tag, osm_way_center, osm_way_end;
-
-static
-xg_tag_mapping osm_map[] = {
-  { osm_node,  cb_start,       "/osm/node" },
-  { osm_node_tag,      cb_start,       "/osm/node/tag" },
-  { osm_node_end,      cb_end,         "/osm/node" },
-  { osm_way,   cb_start,       "/osm/way" },
-  { osm_way_nd,        cb_start,       "/osm/way/nd" },
-  { osm_way_tag,       cb_start,       "/osm/way/tag" },
-  { osm_way_center,    cb_start,       "/osm/way/center" },
-  { osm_way_end,       cb_end,         "/osm/way" },
-  { nullptr,   (xg_cb_type)0,          nullptr }
-};
-
-static const char* osm_features[] = {
+const char* const OsmFormat::osm_features[] = {
   "- dummy -", /*  0 */
   "aeroway",   /*  1 */
   "amenity",   /*  2 */
@@ -101,16 +64,9 @@ static const char* osm_features[] = {
   nullptr
 };
 
-struct osm_icon_mapping_t {
-  int key;
-  const char* value;
-  const char* icon;
-};
+  /* based on <http://wiki.openstreetmap.org/index.php/Map_Features> */
 
-
-/* based on <http://wiki.openstreetmap.org/index.php/Map_Features> */
-
-static const osm_icon_mapping_t osm_icon_mappings[] = {
+const OsmFormat::osm_icon_mapping_t OsmFormat::osm_icon_mappings[] = {
 
   /* cycleway ...*/
 
@@ -413,13 +369,12 @@ static const osm_icon_mapping_t osm_icon_mappings[] = {
   { -1, nullptr, nullptr }
 };
 
-
 /*******************************************************************************/
 /*                                   READER                                    */
 /*-----------------------------------------------------------------------------*/
 
-static void
-osm_features_init()
+void
+OsmFormat::osm_features_init()
 {
   /* the first of osm_features is a place holder */
   for (int i = 1; osm_features[i]; ++i) {
@@ -432,16 +387,14 @@ osm_features_init()
   }
 }
 
-
-static char
-osm_feature_ikey(const QString& key)
+char
+OsmFormat::osm_feature_ikey(const QString& key) const
 {
   return keys.value(key, -1);
 }
 
-
-static QString
-osm_feature_symbol(const int ikey, const char* value)
+QString
+OsmFormat::osm_feature_symbol(const int ikey, const char* value) const
 {
   QPair<int, QString> key(ikey, value);
 
@@ -454,16 +407,15 @@ osm_feature_symbol(const int ikey, const char* value)
   return result;
 }
 
-
-static char*
-osm_strip_html(const char* str)
+char*
+OsmFormat::osm_strip_html(const char* str)
 {
   utf_string utf(true, str);
   return strip_html(&utf);     // util.cc
 }
 
-static QString
-osm_strip_html(const QString& str)
+QString
+OsmFormat::osm_strip_html(const QString& str) const
 {
   char* r = osm_strip_html(CSTR(str));
   QString rv(r);
@@ -471,9 +423,8 @@ osm_strip_html(const QString& str)
   return rv;
 }
 
-
-static void
-osm_node_end(xg_string, const QXmlStreamAttributes*)
+void
+OsmFormat::osm_node_end(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   if (wpt) {
     if (wpt->wpt_flags.fmt_use) {
@@ -485,9 +436,8 @@ osm_node_end(xg_string, const QXmlStreamAttributes*)
   }
 }
 
-
-static void
-osm_node(xg_string, const QXmlStreamAttributes* attrv)
+void
+OsmFormat::osm_node(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
 {
   wpt = new Waypoint;
 
@@ -517,9 +467,8 @@ osm_node(xg_string, const QXmlStreamAttributes* attrv)
   }
 }
 
-
-static void
-osm_node_tag(xg_string, const QXmlStreamAttributes* attrv)
+void
+OsmFormat::osm_node_tag(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
 {
   QString key, value;
   signed char ikey;
@@ -571,9 +520,8 @@ osm_node_tag(xg_string, const QXmlStreamAttributes* attrv)
   }
 }
 
-
-static void
-osm_way(xg_string, const QXmlStreamAttributes* attrv)
+void
+OsmFormat::osm_way(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
 {
   rte = new route_head;
   // create a wpt to represent the route center if it has a center tag
@@ -583,8 +531,8 @@ osm_way(xg_string, const QXmlStreamAttributes* attrv)
   }
 }
 
-static void
-osm_way_nd(xg_string, const QXmlStreamAttributes* attrv)
+void
+OsmFormat::osm_way_nd(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
 {
   if (attrv->hasAttribute("ref")) {
     QString atstr = attrv->value("ref").toString();
@@ -599,8 +547,8 @@ osm_way_nd(xg_string, const QXmlStreamAttributes* attrv)
   }
 }
 
-static void
-osm_way_tag(xg_string, const QXmlStreamAttributes* attrv)
+void
+OsmFormat::osm_way_tag(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
 {
   QString key, value;
   signed char ikey;
@@ -636,8 +584,8 @@ osm_way_tag(xg_string, const QXmlStreamAttributes* attrv)
   }
 }
 
-static void
-osm_way_center(xg_string, const QXmlStreamAttributes* attrv)
+void
+OsmFormat::osm_way_center(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
 {
   wpt->wpt_flags.fmt_use = 1;
 
@@ -649,8 +597,8 @@ osm_way_center(xg_string, const QXmlStreamAttributes* attrv)
   }
 }
 
-static void
-osm_way_end(xg_string, const QXmlStreamAttributes*)
+void
+OsmFormat::osm_way_end(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   if (rte) {
     route_add_head(rte);
@@ -661,14 +609,14 @@ osm_way_end(xg_string, const QXmlStreamAttributes*)
     if (wpt->wpt_flags.fmt_use) {
       waypt_add(wpt);
     } else {
-      delete(wpt);
+      delete wpt;
       wpt = nullptr;
     }
   }
 }
 
-static void
-osm_rd_init(const QString& fname)
+void
+OsmFormat::rd_init(const QString& fname)
 {
   wpt = nullptr;
   rte = nullptr;
@@ -678,17 +626,17 @@ osm_rd_init(const QString& fname)
     osm_features_init();
   }
 
-  xml_init(fname, osm_map, nullptr);
+  xml_init(fname, build_xg_tag_map(this, osm_map), nullptr, nullptr, nullptr, true);
 }
 
-static void
-osm_read()
+void
+OsmFormat::read()
 {
   xml_read();
 }
 
-static void
-osm_rd_deinit()
+void
+OsmFormat::rd_deinit()
 {
   xml_deinit();
   waypoints.clear();
@@ -698,8 +646,8 @@ osm_rd_deinit()
 /*                                   WRITER                                    */
 /*-----------------------------------------------------------------------------*/
 
-static void
-osm_init_icons()
+void
+OsmFormat::osm_init_icons()
 {
   if (!icons.isEmpty()) {
     return;
@@ -710,8 +658,8 @@ osm_init_icons()
   }
 }
 
-static void
-osm_write_tag(const QString& key, const QString& value)
+void
+OsmFormat::osm_write_tag(const QString& key, const QString& value) const
 {
   if (!value.isEmpty()) {
     char* str = xml_entitize(CSTR(value));
@@ -720,8 +668,8 @@ osm_write_tag(const QString& key, const QString& value)
   }
 }
 
-static void
-osm_disp_feature(const Waypoint* waypoint)
+void
+OsmFormat::osm_disp_feature(const Waypoint* waypoint) const
 {
   if (icons.contains(waypoint->icon_descr)) {
     const osm_icon_mapping_t* map = icons.value(waypoint->icon_descr);
@@ -729,8 +677,8 @@ osm_disp_feature(const Waypoint* waypoint)
   }
 }
 
-static void
-osm_write_opt_tag(const char* atag)
+void
+OsmFormat::osm_write_opt_tag(const char* atag)
 {
   char* cin;
 
@@ -758,18 +706,17 @@ osm_write_opt_tag(const char* atag)
   xfree(tag);
 }
 
-static void
-osm_release_ids(const Waypoint* waypoint)
+void
+OsmFormat::osm_release_ids(const Waypoint* waypoint)
 {
   if (waypoint && waypoint->extra_data) {
-    auto* tmp = const_cast<Waypoint*>(waypoint);
-    xfree(tmp->extra_data);
-    tmp->extra_data = nullptr;
+    delete static_cast<int*>(waypoint->extra_data);
+    const_cast<Waypoint*>(waypoint)->extra_data = nullptr;
   }
 }
 
-static QString
-osm_name_from_wpt(const Waypoint* waypoint)
+QString
+OsmFormat::osm_name_from_wpt(const Waypoint* waypoint)
 {
   QString name = QString("%1\01%2\01%3")
                  .arg(waypoint->shortname)
@@ -778,8 +725,8 @@ osm_name_from_wpt(const Waypoint* waypoint)
   return name;
 }
 
-static void
-osm_waypt_disp(const Waypoint* waypoint)
+void
+OsmFormat::osm_waypt_disp(const Waypoint* waypoint)
 {
   QString name = osm_name_from_wpt(waypoint);
 
@@ -789,9 +736,9 @@ osm_waypt_disp(const Waypoint* waypoint)
 
   waypoints.insert(name, waypoint);
 
-  int* id = (int*) xmalloc(sizeof(*id));
+  auto* id = new int;
   *id = --node_id;
-  (const_cast<Waypoint*>(waypoint))->extra_data = id;
+  const_cast<Waypoint*>(waypoint)->extra_data = id;
 
   gbfprintf(fout, "  <node id='%d' visible='true' lat='%0.7f' lon='%0.7f'", *id, waypoint->latitude, waypoint->longitude);
   if (waypoint->creation_time.isValid()) {
@@ -844,7 +791,7 @@ osm_waypt_disp(const Waypoint* waypoint)
   }
 
   osm_write_tag("name", waypoint->shortname);
-  osm_write_tag("note", (waypoint->notes.isEmpty()) ? waypoint->description : waypoint->notes);
+  osm_write_tag("note", waypoint->notes.isEmpty() ? waypoint->description : waypoint->notes);
   if (!waypoint->icon_descr.isNull()) {
     osm_disp_feature(waypoint);
   }
@@ -854,10 +801,10 @@ osm_waypt_disp(const Waypoint* waypoint)
   gbfprintf(fout, "  </node>\n");
 }
 
-static void
-osm_rte_disp_head(const route_head* route)
+void
+OsmFormat::osm_rte_disp_head(const route_head* route)
 {
-  skip_rte = (route->rte_waypt_ct <= 0);
+  skip_rte = route->rte_waypt_ct <= 0;
 
   if (skip_rte) {
     return;
@@ -866,8 +813,8 @@ osm_rte_disp_head(const route_head* route)
   gbfprintf(fout, "  <way id='%d' visible='true'>\n", --node_id);
 }
 
-static void
-osm_rtept_disp(const Waypoint* wpt_ref)
+void
+OsmFormat::osm_rtept_disp(const Waypoint* wpt_ref) const
 {
   QString name = osm_name_from_wpt(wpt_ref);
 
@@ -877,13 +824,13 @@ osm_rtept_disp(const Waypoint* wpt_ref)
 
   if (waypoints.contains(name)) {
     const Waypoint* waypoint = waypoints.value(name);
-    int* id = (int*) waypoint->extra_data;
+    auto* id = static_cast<int*>(waypoint->extra_data);
     gbfprintf(fout, "    <nd ref='%d'/>\n", *id);
   }
 }
 
-static void
-osm_rte_disp_trail(const route_head* route)
+void
+OsmFormat::osm_rte_disp_trail(const route_head* route)
 {
   if (skip_rte) {
     return;
@@ -910,8 +857,8 @@ osm_rte_disp_trail(const route_head* route)
 
 /*-----------------------------------------------------------------------------*/
 
-static void
-osm_wr_init(const QString& fname)
+void
+OsmFormat::wr_init(const QString& fname)
 {
   fout = gbfopen(fname, "w", MYNAME);
 
@@ -920,8 +867,8 @@ osm_wr_init(const QString& fname)
   node_id = 0;
 }
 
-static void
-osm_write()
+void
+OsmFormat::write()
 {
   gbfprintf(fout, "<?xml version='1.0' encoding='UTF-8'?>\n");
   gbfprintf(fout, "<osm version='0.6' generator='GPSBabel");
@@ -930,18 +877,30 @@ osm_write()
   }
   gbfprintf(fout, "'>\n");
 
-  waypt_disp_all(osm_waypt_disp);
-  route_disp_all(nullptr, nullptr, osm_waypt_disp);
-  track_disp_all(nullptr, nullptr, osm_waypt_disp);
-
-  route_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp);
-  track_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp);
+  auto osm_waypt_disp_lambda = [this](const Waypoint* waypointp)->void {
+    osm_waypt_disp(waypointp);
+  };
+  waypt_disp_all(osm_waypt_disp_lambda);
+  route_disp_all(nullptr, nullptr, osm_waypt_disp_lambda);
+  track_disp_all(nullptr, nullptr, osm_waypt_disp_lambda);
+
+  auto osm_rte_disp_head_lambda = [this](const route_head* rte)->void {
+    osm_rte_disp_head(rte);
+  };
+  auto osm_rte_disp_trail_lambda = [this](const route_head* rte)->void {
+    osm_rte_disp_trail(rte);
+  };
+  auto osm_rtept_disp_lambda = [this](const Waypoint* waypointp)->void {
+    osm_rtept_disp(waypointp);
+  };
+  route_disp_all(osm_rte_disp_head_lambda, osm_rte_disp_trail_lambda, osm_rtept_disp_lambda);
+  track_disp_all(osm_rte_disp_head_lambda, osm_rte_disp_trail_lambda, osm_rtept_disp_lambda);
 
   gbfprintf(fout, "</osm>\n");
 }
 
-static void
-osm_wr_deinit()
+void
+OsmFormat::wr_deinit()
 {
   gbfclose(fout);
 
@@ -952,8 +911,8 @@ osm_wr_deinit()
   waypoints.clear();
 }
 
-static void
-osm_exit()
+void
+OsmFormat::exit()
 {
   keys.clear();
   values.clear();
@@ -961,22 +920,3 @@ osm_exit()
 }
 
 /*-----------------------------------------------------------------------------*/
-
-ff_vecs_t osm_vecs = {
-  ff_type_file,
-  {
-    (ff_cap)(ff_cap_read | ff_cap_write)       /* waypoints */,
-    ff_cap_write                       /* tracks */,
-    (ff_cap)(ff_cap_read | ff_cap_write)       /* routes */,
-  },
-  osm_rd_init,
-  osm_wr_init,
-  osm_rd_deinit,
-  osm_wr_deinit,
-  osm_read,
-  osm_write,
-  osm_exit,
-  &osm_args,
-  CET_CHARSET_UTF8, 0
-  , NULL_POS_OPS,
-  nullptr};
diff --git a/osm.h b/osm.h
new file mode 100644 (file)
index 0000000..7147322
--- /dev/null
+++ b/osm.h
@@ -0,0 +1,156 @@
+/*
+
+       Support for "OpenStreetMap" data files (.xml)
+
+       Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+*/
+#ifndef OSM_H_INCLUDED_
+#define OSM_H_INCLUDED_
+
+#include <QtCore/QHash>                 // for QHash
+#include <QtCore/QList>                 // for QList
+#include <QtCore/QPair>                 // for QPair
+#include <QtCore/QString>               // for QString
+#include <QtCore/QVector>               // for QVector
+#include <QtCore/QXmlStreamAttributes>  // for QXmlStreamAttributes
+
+#include "defs.h"
+#include "format.h"                     // for Format
+#include "gbfile.h"                     // for gbfile
+#include "xmlgeneric.h"                 // for xg_functor_map_entry, cb_start, cb_end, xg_string
+
+
+class OsmFormat : public Format
+{
+public:
+  /* Member Functions */
+
+  QVector<arglist_t>* get_args() override
+  {
+    return &osm_args;
+  }
+
+  ff_type get_type() const override
+  {
+    return ff_type_file;
+  }
+
+  QVector<ff_cap> get_cap() const override
+  {
+    return {
+      (ff_cap)(ff_cap_read | ff_cap_write)     /* waypoints */,
+      ff_cap_write                     /* tracks */,
+      (ff_cap)(ff_cap_read | ff_cap_write)     /* routes */,
+    };
+  }
+
+  QString get_encode() const override
+  {
+    return CET_CHARSET_UTF8;
+  }
+
+  int get_fixed_encode() const override
+  {
+    return 0;
+  }
+
+  void rd_init(const QString& fname) override;
+  void read() override;
+  void rd_deinit() override;
+  void wr_init(const QString& fname) override;
+  void write() override;
+  void wr_deinit() override;
+  void exit() override;
+
+private:
+  /* Types */
+
+  struct osm_icon_mapping_t {
+    int key;
+    const char* value;
+    const char* icon;
+  };
+
+  /* Constants */
+
+  static const char* const osm_features[];
+  static const osm_icon_mapping_t osm_icon_mappings[];
+
+  /* Member Functions */
+
+  void osm_features_init();
+  char osm_feature_ikey(const QString& key) const;
+  QString osm_feature_symbol(int ikey, const char* value) const;
+  static char* osm_strip_html(const char* str);
+  QString osm_strip_html(const QString& str) const;
+  void osm_node_end(xg_string /* unused */, const QXmlStreamAttributes* /* unused */);
+  void osm_node(xg_string /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_node_tag(xg_string /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_way(xg_string /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_way_nd(xg_string /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_way_tag(xg_string /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_way_center(xg_string /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_way_end(xg_string /* unused */, const QXmlStreamAttributes* /* unused */);
+  void osm_init_icons();
+  void osm_write_tag(const QString& key, const QString& value) const;
+  void osm_disp_feature(const Waypoint* waypoint) const;
+  void osm_write_opt_tag(const char* atag);
+  static void osm_release_ids(const Waypoint* waypoint);
+  static QString osm_name_from_wpt(const Waypoint* waypoint);
+  void osm_waypt_disp(const Waypoint* waypoint);
+  void osm_rte_disp_head(const route_head* route);
+  void osm_rtept_disp(const Waypoint* wpt_ref) const;
+  void osm_rte_disp_trail(const route_head* route);
+
+  /* Data Members */
+
+  char* opt_tag{};
+  char* opt_tagnd{};
+  char* created_by{};
+
+  QVector<arglist_t> osm_args = {
+    { "tag", &opt_tag,         "Write additional way tag key/value pairs", nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr},
+    { "tagnd", &opt_tagnd,     "Write additional node tag key/value pairs", nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr },
+    { "created_by", &created_by, "Use this value as custom created_by value","GPSBabel", ARGTYPE_STRING, ARG_NOMINMAX, nullptr },
+  };
+
+  QHash<QString, const Waypoint*> waypoints;
+
+  QHash<QString, int> keys;
+  QHash<QPair<int, QString>, const osm_icon_mapping_t*> values;
+  QHash<QString, const osm_icon_mapping_t*> icons;
+
+  gbfile* fout{};
+  int node_id{};
+  int skip_rte{};
+
+  route_head* rte{};
+  Waypoint* wpt{};
+
+  QList<xg_functor_map_entry<OsmFormat>> osm_map = {
+    {&OsmFormat::osm_node,     cb_start,       "/osm/node"},
+    {&OsmFormat::osm_node_tag, cb_start,       "/osm/node/tag"},
+    {&OsmFormat::osm_node_end, cb_end,         "/osm/node"},
+    {&OsmFormat::osm_way,      cb_start,       "/osm/way"},
+    {&OsmFormat::osm_way_nd,   cb_start,       "/osm/way/nd"},
+    {&OsmFormat::osm_way_tag,  cb_start,       "/osm/way/tag"},
+    {&OsmFormat::osm_way_center,       cb_start,       "/osm/way/center"},
+    {&OsmFormat::osm_way_end,  cb_end,         "/osm/way"}
+  };
+};
+#endif // OSM_H_INCLUDED_
diff --git a/vecs.h b/vecs.h
index f34951ba4f4ed1df2fb9a476e6f2090622954e1c..a8d7de611784f260663bb8290954702eeb37fed4 100644 (file)
--- a/vecs.h
+++ b/vecs.h
@@ -41,6 +41,7 @@
 #include "lowranceusr.h"
 #include "mynav.h"
 #include "nmea.h"
+#include "osm.h"
 #include "qstarz_bl_1000.h"
 #include "random.h"
 #include "shape.h"
@@ -132,7 +133,6 @@ extern ff_vecs_t lmx_vecs;
 extern ff_vecs_t xol_vecs;
 extern ff_vecs_t navilink_vecs;
 extern ff_vecs_t ik3d_vecs;
-extern ff_vecs_t osm_vecs;
 extern ff_vecs_t destinator_poi_vecs;
 extern ff_vecs_t destinator_itn_vecs;
 extern ff_vecs_t destinator_trl_vecs;
@@ -361,7 +361,7 @@ private:
   Dg200FileFormat dg200_ffmt;
   LegacyFormat navilink_fmt {navilink_vecs};
   LegacyFormat ik3d_fmt {ik3d_vecs};
-  LegacyFormat osm_fmt {osm_vecs};
+  OsmFormat osm_fmt;
   LegacyFormat destinator_poi_fmt {destinator_poi_vecs};
   LegacyFormat destinator_itn_fmt {destinator_itn_vecs};
   LegacyFormat destinator_trl_fmt {destinator_trl_vecs};